import React, { useState, useEffect } from 'react';
import uuidv4 from 'uuid/v4'  //生成文件id
import { flattenArr, objToArr } from './utils/FlattenState' //将json专程 flatten state 函数
import fileHelper from './utils/filehelper'  //导入文件操作模块

import 'antd/dist/antd.css';
import './App.css'
import { Layout } from 'antd'
import Filearch from './components/FileSearch'   //导入File search组件
import FileList from './components/FileList'  //导入文件列表组件
import FileListBtn from './components/FileListBtn'  //导入文件列表按钮

import TabList from './components/TabList'  //文件tablist
import useIpcRenderer from './hooks/useIpcRenderer'  //导入 菜单usehooks
// import defaultFiles from './utils/deFaultFiles'  //导入文件列表假数据


const { Sider, Content } = Layout;

const { join,extname,basename,dirname} = require('path')

const { remote,ipcRenderer } = window.require('electron')

const Store = window.require('electron-store')  //数据持久化
const filesStore = new Store({ 'name': 'Files Data' })
const settingsStore = new Store({name: 'Settings'})

const saveFilesToStore = (files) => {     //真数据
  const filesStoreObj = objToArr(files).reduce((result, file) => {
    const { id, path, title, createAt } = file
    result[id] = {
      id,
      path,
      title,
      createAt
    }
    return result
  }, {})
  filesStore.set('files', filesStoreObj)

}


function App() {
  const [files, setFiles] = useState(filesStore.get('files') || {})  //转成 flattenState 格式数据
  // console.log(files)
  const [activeFileId, setActiveFileId] = useState('') //当前正在被激活的文件
  const [openedFileIds, setOpenedFileIds] = useState([]) //当前有哪些打开的文件
  const [searchFiles, setSearchFiles] = useState([]) //搜索的文件数组


  const filesArr = objToArr(files)  //转回来
  // console.log(filesArr)


  // https://www.electronjs.org/docs/all#appgetpathname //参数  方法 文档连接
  const saveLocation = settingsStore.get('savedFileLocation')||remote.app.getPath('desktop')  //文件路径
  // console.log(saveLocation+'\\electron-note');  //默认创建到桌面


  const fileClick = (fileID) => {     //获取子组件传递过来的值
    setActiveFileId(fileID)  //当前正在被激活的文件
    const currentFile=files[fileID]
    if(!currentFile.isLoaded){       //内容持久化
    console.log(currentFile);
    fileHelper.readFile(currentFile.path).then(value=>{
      const newFile ={...files[fileID],body:value,isLoaded:true}
      setFiles({...files,[fileID]:newFile})
    })
    }
    if (!openedFileIds.includes(fileID)) {  //防止重复 激活文件
      setOpenedFileIds([...openedFileIds, fileID])
    }
  }

  const tabClose = (targetKey, action) => {   //从子组件获取 当前点击的tabid
    if (action === 'remove') {  //如果动作是删除的话
      const tabWithOut = openedFileIds.filter(file => file !== parseInt(targetKey))   //targetKey 必须是number

      setOpenedFileIds(tabWithOut)  //修改打开文件的id
    }
  }

  const markdownChange = (id, value) => {     //当子组件 文本变化时将 文本id和文本内容传递 到此函数
    if(value!==files[id].body){
      const newFile = { ...files[id], body: value }
      fileHelper.writeFile(files[id].path, value).then(() => {  //修改 markdown 时 创建 文件
        setFiles({ ...files, [id]: newFile })
      })
    }
  }

  const deleteFile = (id) => {   //从子组件获取 删除文件
    if (files[id].isNew) {
      delete files[id]
      setFiles({ ...files })
    } else {
      fileHelper.deleteFile(files[id].path.replace(/\//g, '\\')).then(() => {
        delete files[id] //新方法
        setFiles({ ...files })
        saveFilesToStore(files)
        tabClose(id, 'remove')  //这里注意执行顺序
      })
    }
  }

  const updateFileName = (id, title) => {  //从子组件获取 修改文件名称
    const newPath = join(saveLocation, `${title}.md`)
    const modifedFile = { ...files[id], isNew: false, title, path: newPath }
    const newFiles = { ...files, [id]: modifedFile }

    if (files[id].title == '') {   //如果是新建文件 就 调用 node.js 创建文件方法
      fileHelper.writeFile(newPath, files[id].body).then(() => {  //修改 markdown 时 创建 文件
        setFiles(newFiles)
        saveFilesToStore(newFiles)
      })
    } else {
      const oldPath = files[id].path
      const jiuPath=join(dirname(files[id].path.replace(/\\/g, '/'))+`/${title}.md`)
      // console.log(jiuPath);
      fileHelper.renameFile(oldPath, jiuPath).then(() => {
        setFiles(newFiles)
        saveFilesToStore(newFiles)
      })
    }
  }

  const fileSearch = (keyword) => {  //从子组件获取 搜索结果 
    const newFiles = filesArr.filter(file => file.title.includes(keyword))  //根据标题搜索文件
    setSearchFiles(newFiles)
  }

  const createNewFile = (action) => {  //新建文件

    const newID = uuidv4()

    const newFile = {
      id: newID,
      path:'',
      title: '',
      body: '## 这是一个新建的markdown',
      createAt: new Date().getTime()
    }
    setFiles({ ...files, [newID]: newFile })
  }

  const AppimportFiles = () => {  //导入文件  调用electron 方法 打开一个对话框
    // https://www.electronjs.org/docs/api/dialog  //参数方法文档地址
    remote.dialog.showOpenDialog({
      title: '选择导入的markdown文件',
      properties: ['openFile', 'multiSelections'],
      filters: [
        { name: 'markdown', extensions: ['md'] }
      ],

    }).then(paths => {
      // console.log(paths.canceled) //布尔值-对话框是否被取消。
      // console.log(paths.filePaths) //tring []-用户选择的文件路径的数组。如果取消对话框，则该数组为空
      if (Array.isArray(paths.filePaths)) {
        const filteredPaths = paths.filePaths.filter(path => {     //不重复导入文件
          const alreadyAdded = Object.values(files).find(file => {
            return file.path === path
          })
          return !alreadyAdded
        })

        const importFilesArr = filteredPaths.map(path => {
          // console.log(basename(path.replace(/\\/g, '/'),extname(path.replace(/\\/g, '/')))) //根据 path 提取出来 文件名称  这里用到了 node basename 方法
          return {
            id: uuidv4(),
            title: basename(path.replace(/\\/g, '/'),extname(path.replace(/\\/g, '/'))), 
            path,
          }
        })
        
        const newFiles={...files,...flattenArr(importFilesArr)}
        setFiles(newFiles)
        saveFilesToStore(newFiles)
        
        if(importFilesArr.length>0){
          remote.dialog.showMessageBox({
            type:'info',
            title:`成功导入了${importFilesArr.length}个文件`,
            message:`成功导入了${importFilesArr.length}个文件`
          })
        }

      }
    })
  }

  const openedFiles = openedFileIds.map(openID => {     //打开的文件只能是文件列表中的
    // return files.find(file => file.id === openID)
    return files[openID]
  })

  const fileListArr = (searchFiles.length > 0) ? searchFiles : filesArr  //根据搜索结果判断


  useIpcRenderer({
    'create-new-file': createNewFile,  //新建文件
    'import-file': AppimportFiles,     //导入文件
    'save-edit-file': markdownChange,  //保存文件
    'search-file':fileSearch, //搜索文件
  })


  return (
    <>
      <Layout style={{ height: '100vh' }}>
        <Sider width={220} style={{ background: '#dfe4e4' }}>   {/* antd中 Sider组件自带 width属性 可以设置宽度  */}
          <Filearch
            onFileSearch={fileSearch}
          ></Filearch> {/* 搜索文本组件  */}
          <FileList
            onFileClick={fileClick}
            onFileDelete={deleteFile}
            onUpdateFile={updateFileName}
            files={fileListArr}></FileList> {/* markdown 列表组件  */}
          <FileListBtn
            onCreateFile={createNewFile}
            importFiles={AppimportFiles}
          ></FileListBtn>{/* 文件列表组件 */}
        </Sider>
        <Content>
          {
            <TabList
              onCloseTab={tabClose}
              fileChange={markdownChange}
              Tabfiles={openedFiles}></TabList>
          }
        </Content>
      </Layout>
    </>
  );
}

export default App;
